/*
    E2020159
    唐琴凤
    2023-9-21
    实践2-class版本
*/
#include <iostream>
using namespace std;
#include <vector>
#include <string.h>
#include<fstream>

#include <stdlib.h>
#include <string.h>

// 判断键盘按下需要的头文件
#include <termio.h>


#include "student.h"
#include "student.cpp"
#include "smart_car.h"
#include "smart_car.cpp"
#include "tire.h"
#include "tire.cpp"
#include "chassis.h"
#include "chassis.cpp"
#include "agx.h"
#include "agx.cpp"
#include "binocular_camera.h"
#include "binocular_camera.cpp"
#include "gyroscope_9axis.h"
#include "gyroscope_9axis.cpp"
#include "multi_line_lidar.h"
#include "multi_line_lidar.cpp"
#include "lcd_isplay_screen.h"
#include "lcd_isplay_screen.cpp"
#include "battery_module.h"
#include "battery_module.cpp"


//  判断键盘按下的函数
int scanKeyboard()
{

    int in;

    struct termios new_settings;
    struct termios stored_settings;
    //设置终端参数
    tcgetattr(0,&stored_settings);
    new_settings = stored_settings;
    new_settings.c_lflag &= (~ICANON);
    new_settings.c_cc[VTIME] = 0;
    tcgetattr(0,&stored_settings);
    new_settings.c_cc[VMIN] = 1;
    tcsetattr(0,TCSANOW,&new_settings);
    in = getchar();
    tcsetattr(0,TCSANOW,&stored_settings);

    return in;

}





// 主函数
int main(){


    

    // 存储10辆小车信息和10名学生信息的容器
    vector<Smart_car>  ve;
    vector<Student> stu_ve;

// 循环输入10辆小车的信息
    while (ve.size()<10)
    {

        // 定义一个小车的变量
        Smart_car smart_car;
        cout<<"请输入第  "<<ve.size()+1<<"号  智能小车的信息：（共需要输入10辆小车的信息）"<<endl;
        // cout<<"请输入智能小车的编号：（cqusn打头的16位数字+字母）："<<endl;
        string id;
        id="cqusn0000000000"+to_string(ve.size()+1);
        if(ve.size()==9)
        id="cqusn0000000000a";

        smart_car.setID(id);

        cout<<"请输入智能小车的底盘编号:(dp打头的8位数字+字母)"<<endl;
        string chassis_id;
        Chassis chassis;
        cin>>chassis_id;

        

// // 判断小车底盘编号的输入是否符合要求
//         flag=0;
//         for(int i=0;i<chassis_id.size();i++){
//             if((chassis_id[i]>'a' && chassis_id[i]<'z') || (chassis_id[i]>'A' && chassis_id[i] < 'Z') || (chassis_id[i] > '0' && chassis_id[i] < '9'))
//             {
//                 flag=1;
//             }
//         }

// // 不符合则重新输入，直到符合要求
//         while (chassis_id.size()!= 8 || chassis_id[0]!='d' || chassis_id[1]!='p'  | flag!=1)
//         {
//             cout<<"输入的底盘编号不符合要求，请重新输入：（dp打头的8位数字+字母）"<<endl;
//             cin>>chassis_id;
//         }
         chassis.setId(chassis_id);

///////////////////////////////////////////////////////////////////////
        if(ve.size()==0)
        {

        string  chassis_model="SCOUT MINI";
        int   wheelbase=451;
        int   track_width=490;
        int   minimum_ground_clearance=115;
        int   minimum_turning_radius=0;
        string  driving_form="四轮四驱";
        int   maximum_stroke=10;
       
       cout<<"请输入智能小车的底盘型号："<<endl;
    //    cin>>chassis_model;
        getline(cin,chassis_model);
        getline(cin,chassis_model);
        chassis.setModel(chassis_model);
        cout<<"请输入智能小车的底盘轴距："<<endl;
        cin>>wheelbase;
        chassis.setWheelbase(wheelbase);
        cout<<"请输入智能小车的底盘轮距："<<endl;
        cin>>track_width;
        chassis.setTrack_width(track_width);
        cout<<"请输入智能小车的底盘最小离地间隙："<<endl;
        cin>>minimum_ground_clearance;
        chassis.setMinimum_ground_clearance(minimum_ground_clearance);
        cout<<"请输入智能小车的底盘最小转弯半径："<<endl;
        cin>>minimum_turning_radius;
        chassis.setMinimum_turning_radius(minimum_turning_radius);
        cout<<"请输入智能小车的底盘驱动形式："<<endl;
        cin>>driving_form;
        chassis.setDriving_form(driving_form);
        cout<<"请输入智能小车的底盘最大行程："<<endl;
        cin>>maximum_stroke;
        chassis.setMaximum_stroke(maximum_stroke);
        cout<<""<<endl;
        
        }


        // flag=0;
        cout<<"请输入智能小车的4个底盘轮胎型号： (1 表示 公路轮   2  表示  麦克纳姆轮)，每个型号之间用空格隔开"<<endl;
        int t1,t2,t3,t4;
        cin>>t1>>t2>>t3>>t4;

        int t_size1=175,t_size2=175,t_size3=175,t_size4=175;
        if(ve.size()==0)
        {
        cout<<"请输入智能小车的4个底盘轮胎尺寸，每个尺寸之间用空格隔开"<<endl;
        cin>>t_size1>>t_size2>>t_size3>>t_size4;

        }

// // 判断小车底盘轮胎型号的输入是否有效
//         if((t1==1 || t1==2) && (t2==1 || t2==2) &&(t3==1 || t3==2) &&(t4==1 || t4==2) )
//         {
//             flag=1;
//         }

// // 输入无效则重新输入，直到有效
//         while (flag!=1)
//         {
//             cout<<"输入的底盘轮胎型号无效,请重新输入：(1 表示 公路轮   2  表示  麦克纳姆轮)，每个型号之间用空格隔开"<<endl;
//             cin>>t1>>t2>>t3>>t4;

//             if((t1==1 || t1==2) && (t2==1 || t2==2) &&(t3==1 || t3==2) &&(t4==1 || t4==2) )
//             {
//                 flag=1;
//             }
//         }

// 把轮胎型号对应到文字上

        Tire t;
        

        if(t1==1){
            t.setSize(t_size1);
            t.setModel("公路轮");
            chassis.setT1(t);
        }else if(t1==2){
            t.setSize(t_size1);
            t.setModel("麦克纳姆轮");
            chassis.setT1(t);
        }

        if(t2==1){
            t.setSize(t_size2);
            t.setModel("公路轮");
            chassis.setT2(t);
        }else if(t2==2){
            t.setSize(t_size2);
            t.setModel("麦克纳姆轮");
            chassis.setT2(t);
        }

        if(t3==1){
            t.setSize(t_size3);
            t.setModel("公路轮");
            chassis.setT3(t);
        }else if(t3==2){
            t.setSize(t_size3);
            t.setModel("麦克纳姆轮");
            chassis.setT3(t);
        }

        if(t4==1){
            t.setSize(t_size4);
            t.setModel("公路轮");
            chassis.setT4(t);
        }else if(t4==2){
            t.setSize(t_size4);
            t.setModel("麦克纳姆轮");
            chassis.setT4(t);
        }


        smart_car.setChassis(chassis);
        // smart_car.print();
        cout<<endl;


// /////////////////////////////////
if(ve.size()==0)
        {
        Agx agx;
        string agx_model="AGX Xavier";
        string ai="32 TOPS";
        int cuda_core=512;
        int tensor_CORE=64;
        int video_storage=32;
        int storage=32;
        cout<<"请输入智能小车的AGX套件型号："<<endl;
        getline(cin,agx_model);
        getline(cin,agx_model);
        agx.setModel(agx_model);

        cout<<"请输入智能小车的AGX套件AI："<<endl;
        // getline(cin,ai);
        getline(cin,ai);
        agx.setAi(ai);
        cout<<"请输入智能小车的AGX套件CUDA核心："<<endl;
        cin>>cuda_core;
        agx.setCuda_core(cuda_core);
        cout<<"请输入智能小车的AGX套件Tensor CORE："<<endl;
        cin>>tensor_CORE;
        agx.setTensor_CORE(tensor_CORE);
        cout<<"请输入智能小车的AGX套件显存："<<endl;
        cin>>video_storage;
        agx.setVidel_storage(video_storage);
        cout<<"请输入智能小车的AGX套件存储："<<endl;
        cin>>storage;
        agx.setStorage(storage);

        smart_car.setAgx(agx);
        cout<<endl;


/////////////// 双目摄像头信息
        Binocular_camera binocular_camera;
        string binocular_camera_model="RealSense D435i";
        string camera="D430";
        string rgb_frame_resolution="1920*1080";
        int rgb_frame_rate=30;
        string fov="87*58";
        int depth_frame_rate=90;

        cout<<"请输入智能小车的双目摄像头型号:"<<endl;
        getline(cin,binocular_camera_model);
        getline(cin,binocular_camera_model);
        binocular_camera.setModel(binocular_camera_model);
        cout<<"请输入智能小车的双目摄像头摄像头:"<<endl;
        cin>>camera;
        binocular_camera.setCamera(camera);
        cout<<"请输入智能小车的双目摄像头RGB帧分辨率:"<<endl;
        cin>>rgb_frame_resolution;
        binocular_camera.setRgb_frame_resolution(rgb_frame_resolution);
        cout<<"请输入智能小车的双目摄像头RGB帧率:"<<endl;
        cin>>rgb_frame_rate;
        binocular_camera.setRgv_fram_rate(rgb_frame_rate);
        cout<<"请输入智能小车的双目摄像头FOV:"<<endl;
        cin>>fov;
        binocular_camera.setFov(fov);
        cout<<"请输入智能小车的双目摄像头深度帧率:"<<endl;
        cin>>depth_frame_rate;
        binocular_camera.setDepth_fram_rate(depth_frame_rate);

        smart_car.setBinocular_camera(binocular_camera);
         cout<<endl;

////////// 多线激光雷达（1个） 
        Multi_line_lidar multi_line_lidar;

        string multi_line_lidar_model="RS-Helios-16p";
        int channels=16;
        int test_range=100;
        int power_consumption=8;

        cout<<"请输入智能小车的多线激光雷达型号："<<endl;
        cin>>multi_line_lidar_model;
        multi_line_lidar.setModel(multi_line_lidar_model);
        cout<<"请输入智能小车的多线激光雷达通道数："<<endl;
        cin>>channels;
        multi_line_lidar.setChannels(channels);
        cout<<"请输入智能小车的多线激光雷达测试范围："<<endl;
        cin>>test_range;
        multi_line_lidar.setTest_range(test_range);
        cout<<"请输入智能小车的多线激光雷达功耗："<<endl;
        cin>>power_consumption;
        multi_line_lidar.setPower_consumption(power_consumption);

        smart_car.setMulti_line_lidar(multi_line_lidar);
        cout<<endl;

// /////////////////////9轴陀螺仪（1个）
        Gyroscope_9axis gyroscope_9axis;

        string gyroscope_9axis_model="CH110";
        string manufacturer="NXP";

        cout<<"请输入智能小车的9轴陀螺仪型号："<<endl;
        cin>>gyroscope_9axis_model;
        gyroscope_9axis.setManufacturer(gyroscope_9axis_model);
        cout<<"请输入智能小车的9轴陀螺仪厂家："<<endl;
        cin>>manufacturer;
        gyroscope_9axis.setManufacturer(manufacturer);

        smart_car.setGyroscope_9axis(gyroscope_9axis);
        cout<<endl;


///////////////////// 液晶显示屏（1个）
        Lcd_isplay_screen lcd_isplay_screen;
        float size=11.6;
        string lcd_isplay_screen_model="super";

        cout<<"请输入智能小车的液晶显示屏尺寸:"<<endl;
        cin>>size;
        lcd_isplay_screen.setSize(size);
        cout<<"请输入智能小车的液晶显示屏型号:"<<endl;
        cin>>lcd_isplay_screen_model;
        lcd_isplay_screen.setModel(lcd_isplay_screen_model);

        smart_car.setLcd_isplay_screen(lcd_isplay_screen);
        cout<<endl;


////////////// 电池模块
        Battery_module battery_module;

        string parameter="24V/15Ah";
        int external_power_supply=24;
        int charging_duration=2;

        cout<<"请输入智能小车的电池模块参数:"<<endl;
        cin>>parameter;
        battery_module.setParameter(parameter);
        cout<<"请输入智能小车的电池模块对外供电:"<<endl;
        cin>>external_power_supply;
        battery_module.setExternal_power_supply(external_power_supply);
        cout<<"请输入智能小车的电池模块充电时长:"<<endl;
        cin>>charging_duration;
        battery_module.setCharging_duration(charging_duration);

        smart_car.seBattery_module(battery_module);
        cout<<endl;


        }




// // 将smar_car 变量push到ve中
        ve.push_back(smart_car);
        cout<<endl;


    }

    cout<<endl;
    cout<<endl;

// 循环输入10名学生的信息
    while (stu_ve.size()<10)
    {
        Student student;
        cout<<"请输入第  "<<stu_ve.size()+1<<"号  学生的信息：（共需要输入10名学生的信息）"<<endl;
        cout<<"请输入该学生的学号："<<endl;
        string stu_id;
        cin>>stu_id;
        student.setId(stu_id);
        cout<<"请输入该学生的姓名："<<endl;
        string stu_name;
        cin>>stu_name;
        student.setName(stu_name);
        stu_ve.push_back(student);
        cout<<endl;


        // student.print();
    }


// 循环写数据到car.txt文件中
string path="car_student.txt";
string su_path="student.txt";
string ve_path="smart_car.txt";
    for(int i=0;i<ve.size();i++)
    {
        stu_ve[i].save(path);
        ofstream ofs;// 创建流对象
        ofs.open(path, ios::out | ios::app);
        ofs<<endl;
        ofs.close();
        ve[i].save(path);
        // ofstream ofs;// 创建流对象
        ofs.open(path, ios::out | ios::app);
        ofs<<endl;
        ofs.close();

        stu_ve[i].save(su_path);
        ve[i].save(ve_path);
    }



// 创建一个读数据的文件流对象
    ifstream readFile;
    readFile.open(path, ios::in);
    vector<string> txt_car;

// 打开文件进行读操作
    if (readFile.is_open())
    {
        cout << "打开文件成功!" << endl;
        string str;
// 循环读取到文件的末尾，存储到txt_car容器中
        while (getline(readFile,str))
        {
            // cout << str << endl;
            txt_car.push_back(str);
        }

        // for(int i=0+56;i<56+56 ;i++)
        // {
        //     // cout<<str<<endl;
        //     cout<<txt_car[i]<<endl;
        // }


        char c;
        int count=0;
// 显示第1个小车的数据
//////////////////////////////////////////////////////////////////////////////////////////////////////////                       57这个数字还得再考虑一下，有的数据显示不全
        for(int i=0;i<57 &&i<txt_car.size();i++)
        {
            cout<<txt_car[i]<<endl;
        }

// 循环进入判断键盘的按下操作
        while (true)
        {
            cout<<"\n按n键显示下一辆小车信息，按p显示上一辆小车信息，按下q表示退出程序："<<endl;

            c=0;
            c=scanKeyboard();
            // cin>>c;

            if(c=='n'){
                cout<<endl;
                if(count==9){
                    cout<<"\n当前显示的为第10台小车，按n无效"<<endl;
                }else{
                    count++;
                    // for的参数还有点问题
                    for(int i=count*57;i<count*57+57-1 &&i<txt_car.size();i++)
                        {
                            cout<<txt_car[i]<<endl;
                        }
                }
            }

            if(c=='p'){
                cout<<endl;
                if(count==0){
                    cout<<"\n当前显示的为第1台小车，按p无效"<<endl;
                }else{
                    count--;
                    // for的参数还有点问题
                    for(int i=count*57;i<count*57+57-1 &&i<txt_car.size();i++)
                        {
                            cout<<txt_car[i]<<endl;
                        }
                }
            }


            if(c=='q'){
                cout<<endl;
                break;
            }
        }




    }
    else
    {
        cout << "打开文件失败!" << endl;
    }
//  关闭读文件流对象
    readFile.close();




    return 0;
}
